/*
 * 版权所有 (C) 2015 知启蒙(ZHIQIM) 保留所有权利。[遇见知启蒙，邂逅框架梦，本文采用木兰宽松许可证第2版]
 * 
 * https://zhiqim.org/project/zhiqim_kit/zhiqim_git.htm
 *
 * ZhiqimGit is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *          http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 */
package org.zhiqim.git.objer.objectid;

import java.io.IOException;
import java.nio.charset.Charset;

import org.zhiqim.git.GitWalker;
import org.zhiqim.git.objer.model.PersonIdent;
import org.zhiqim.git.objer.model.Tag;
import org.zhiqim.git.util.GitBytes;

import org.zhiqim.kernel.util.mutables.MInt;
import org.zhiqim.kernel.util.Bytes;

/**
 * 修改过程中的附注标签对象
 * 
 * object 6f07a489f21c77047449ec4cff783f311d47c74b
 * type commit
 * tag V1.0.1
 * tagger zzg <zzg@zhiqim.org> 1490842716 +0800
 * 
 * 发布V1.0.1版本
 * 
 * @version v1.0.0 @author zhichenggang 2017-3-28 新建与整理
 */
public class RevTag extends RevObject
{
    private RevObject object;
    private String tagName;
    private PersonIdent tagger;
    private byte[] buffer;
    
    public RevTag(final ObjectId id)
    {
        super(id);
    }

    /***********************************************************************/
    //子类必须实现的4个方法
    /***********************************************************************/
    
    @Override
    public final int getType()
    {
        return OBJ_TAG;
    }
    
    @Override
    public void parseHeaders(GitWalker walk) throws IOException
    {
        parseCanonical(walk, loadCanonical(walk));
    }

    @Override
    public void parseBody(GitWalker walk) throws IOException
    {
        if (buffer == null)
        {
            buffer = loadCanonical(walk);
            if (!isParsed())
                parseCanonical(walk, buffer);
        }
    }
    
    @Override
    public final byte[] getContent()
    {
        return buffer;
    }
    
    @Override
    public final void disposeContent()
    {
        buffer = null;
    }
    
    /***********************************************************************/
    //解析内容
    /***********************************************************************/
    
    /**
     * 解析内容
     * 
     * object 6f07a489f21c77047449ec4cff783f311d47c74b
     * type commit
     * tag V1.0.1
     * tagger zzg <zzg@zhiqim.org> 1490842716 +0800
     * 
     * 发布V1.0.1版本
     * 
     * @param walk      步行器
     * @param data      字节数据
     */
    public void parseCanonical(GitWalker walk, final byte[] data)
    {
        MInt off = new MInt();
        
        //1.读取对象编号、类型和标签名称
        off.skip(7);//object 
        String oid = Bytes.BU.getString(data, off, '\n');
        
        off.skip(5);//type 
        String type = Bytes.BU.getString(data, off, '\n');
        
        off.skip(4);//tag 
        tagName = Bytes.BU.getString(data, off, '\n');
        
        off.skip(6);//tagger 
        tagger = new PersonIdent(Bytes.BU.getString(data, off, '\n'));
        
        //2.读取对象
        int typeInt = type(type);
        object = walk.lookup(ObjectId.parse(oid), typeInt);

        //3.保存内容
        if (walk.isRetainBody())
            buffer = data;
        
        //4.置为已解析
        setParsed();
    }
    
    /***********************************************************************/
    //获取属性
    /***********************************************************************/

    public final RevObject getObject()
    {
        return object;
    }

    public final String getTagName()
    {
        return tagName;
    }

    public final PersonIdent getTagger()
    {
        return tagger;
    }

    /** 获取标签完整消息 */
    public final String getFullMessage()
    {
        int off = GitBytes.paragraph(buffer, 0);
        if (off == buffer.length)
            return "";

        //读取可能的字符集
        Charset charset = GitBytes.encoding(buffer);
        return new String(buffer, off+1, buffer.length-off, charset);
    }

    /** 获取标签简短消息（第一段落），并去除换行符 */
    public final String getShortMessage()
    {
        int off = GitBytes.paragraph(buffer, 0);
        if (off == buffer.length)
            return "";
        
        Charset charset = GitBytes.encoding(buffer);
        int paragraph = GitBytes.paragraph(buffer, off+1);
        String message = new String(buffer, off, paragraph-off, charset);
        if (hasLF(buffer, off, paragraph))
            message = message.replace('\n', ' ');
        
        return message;
    }

    /***********************************************************************/
    //转为对象
    /***********************************************************************/
    
    /** 转化为标签对象 */
    public Tag asTag()
    {
        return new Tag().parse(buffer);
    }
}
